import vtkmodules.all as vtk
from enum import Enum


class WidgetState(Enum):
    VTK_IS_START = 0
    VTK_IS_ROTATE = 1
    VTK_IS_PAN = 2
    VTK_IS_SPIN = 3
    VTK_IS_DOLLY = 4
    VTK_IS_ZOOM = 5
    VTK_IS_USCALE = 6
    VTK_IS_TIMER = 7
    VTK_IS_FORWARDFLY = 8
    VTK_IS_REVERSEFLY = 9
    VTK_IS_TWO_POINTER = 10


class ITrackballSimpleCamera(vtk.vtkInteractorStyleTrackballCamera):
    m_accept_mouse_move = False
    height = None

    def IsPanning(self):
        return self.GetState() == WidgetState.VTK_IS_PAN

    def CanAcceptMouseMove(self):
        return self.m_accept_mouse_move

    def UpdateMousePosition(self, x, y):
        self.GetInteractor().SetEventPosition(x, y)

    def TriggerPan(self, x, y):
        # print("[ITrackballSimpleCamera] 右键 ↓", x, y)
        self.UpdateMousePosition(x, self.flip_y(y))
        self.OnMiddleButtonDown()
        self.m_accept_mouse_move = True

    def TriggerEndPan(self, x, y):
        # print("[ITrackballSimpleCamera] 右键 ↑", x, y)
        self.UpdateMousePosition(x, self.flip_y(y))
        self.OnMiddleButtonUp()
        self.m_accept_mouse_move = False

    def TriggerRotate(self, x, y):
        # print("[ITrackballSimpleCamera] 左键 ↓", x, y)
        self.UpdateMousePosition(x, self.flip_y(y))
        self.OnLeftButtonDown()
        self.m_accept_mouse_move = True

    def TriggerEndRotate(self, x, y):
        # print("[ITrackballSimpleCamera] 左键 ↑", x, y)
        self.UpdateMousePosition(x, self.flip_y(y))
        self.OnLeftButtonUp()
        self.m_accept_mouse_move = False

    def TriggerZoomDelta(self, delta):
        if delta == 0:
            return
        if delta > 0:
            self.GetCurrentRenderer().GetActiveCamera().Zoom(1.1)
        else:
            self.GetCurrentRenderer().GetActiveCamera().Zoom(0.9)
        self.GetCurrentRenderer().ResetCameraClippingRange()
        self.GetCurrentRenderer().GetRenderWindow().Render()

    def TriggerMouseMove(self, x, y):
        if not self.CanAcceptMouseMove():
            return

        self.UpdateMousePosition(x, self.flip_y(y))
        self.OnMouseMove()

    # 坐标系变换
    def flip_y(self, y) -> int:
        if self.height is None:
            self.height = self.GetInteractor().GetRenderWindow().GetSize()[1]
        return self.height - y
